package definition

import (
	"codejy/analysis/lineanalysis"
	"codejy/globalfunc"
	"codejy/store"
	"codejy/structdef"
	"codejy/utils"
	"strings"
)

type FuncDefanalysis struct {
	//优先级
	priority int
}

func init() {
	RegisterDefinition(&FuncDefanalysis{priority: 1})
}
func (f *FuncDefanalysis) GetPriority() int {
	return f.priority
}

func (f FuncDefanalysis) ParseDefinition(codes *[]structdef.LineCodeDefinition, realityFilePath string) {

	GetMethodsDef(codes, realityFilePath)
}

// 注册函数定义,返回函数名
func GetMethodsDef(currentLineCodes *[]structdef.LineCodeDefinition, realityFilePath string) {
	var annotations = make(map[string]map[string]string)
	for i := 0; i < len(*currentLineCodes); {
		currentLineCode := (*currentLineCodes)[i]
		if currentLineCode.LineCodeType == lineanalysis.FunctionDefine {
			//向上找注解直到遇到}或者没有了
			if i > 0 {
				for j1 := i - 1; j1 >= 0; j1-- {
					currentLineCode1 := (*currentLineCodes)[j1]
					//如果是}，则结束
					if currentLineCode1.LineContent == "}" {
						break
					}
					//判断是否是注解
					if globalfunc.ExecuteFunc("IsAnnotation", currentLineCode1.LineContent).(bool) {
						annotationName, annotationParams := utils.ExtractAnnotation(currentLineCode1.LineContent)
						annotations[annotationName] = annotationParams
						//删除排除的行
						*currentLineCodes = append((*currentLineCodes)[:j1], (*currentLineCodes)[j1+1:]...)
						i--
						continue
					}
				}
			}

			var codelines []structdef.LineCodeDefinition
			//截取函数名
			funcName := (*currentLineCodes)[i].LineContent[strings.Index(currentLineCode.LineContent, "func")+4:]
			//排除结尾{
			funcName = funcName[0:strings.Index(funcName, "{")]
			//判断函数名是否合法
			globalfunc.ExecuteFunc("IsVariableNameLegal", funcName)
			//删除跳过的行
			*currentLineCodes = append((*currentLineCodes)[:i], (*currentLineCodes)[i+1:]...)
			//解析函数定义 ,从函数定义开始，往下找到函数体结束
			var num = 1
			for j := i; j < len(*currentLineCodes); {
				currentLineCode = (*currentLineCodes)[j]
				codelines = append(codelines, currentLineCode)
				//删除跳过的行
				*currentLineCodes = append((*currentLineCodes)[:j], (*currentLineCodes)[j+1:]...)
				if strings.HasSuffix(currentLineCode.LineContent, "{") {
					num++
				}
				if strings.HasPrefix(currentLineCode.LineContent, "}") {
					num--
				}
				if num == 0 { //函数体结束
					//跳过最后}
					codelines = codelines[:len(codelines)-1]
					codelines = structdef.AnalyseLineCodeDefinitions(store.MainThreadStore, codelines, realityFilePath)
					store.RegisterFunDefinition(realityFilePath, funcName, structdef.NewFuncDefinition(funcName, codelines, annotations))
					//清空注解
					annotations = make(map[string]map[string]string)
					break
				}

			}

		} else {
			//不是函数继续往下找
			i++
		}

	}
}
